package com.cim.utils;

import com.cim.config.GlobalConfig;
import com.cim.storage.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;


@Component
//视频合并工具类
//可能存在权限问题导致读写失败 暂未解决
public class VideoConcatUtil {
    @Autowired
    static StorageService storageService=new StorageService();
    private static final String VIDEO_LIST_FILE_NAME="videoList.txt";
    //将以startName开头的多个视频 合并成一个视频 取合并后的视频的md5并返回
    public static String concat(String startName){
        //获取RTMP保存目录
        File file=new File(GlobalConfig.RTMP_RECORD_PATH);
        Path path=file.toPath();
        //获取文件名以startName开头的文件列表
        File[] targerList= file.listFiles((dir, name) -> name.startsWith(startName+"-"));
        //如果没有任何视频,返回null
        if(targerList.length==0){
            return null;
        }

        //获取列表中第0个视频的后缀名
        String firstFileName=targerList[0].getName();
        int index = firstFileName.lastIndexOf('.');
        String extendsName=firstFileName.substring(index);
        //合成输出文件名 ：前缀名+后缀名
        String outFileName=startName+extendsName;

        //获取该目录下的一个临时文件用于存放需要被合并的视频列表
        File fileListTxt=path.resolve(VIDEO_LIST_FILE_NAME).toFile();
        //如果文件存在 则删除文件以清空内容
        if(fileListTxt.exists()){
            fileListTxt.delete();
        }
        try {
            fileListTxt.createNewFile();
        } catch (IOException e) {
            //创建临时文件失败
            throw new RuntimeException("创建视频合并列表临时文件失败:"+e);
        }

        //将视频列表写入临时文件
        for(File f:targerList){
            try {
                Files.write(fileListTxt.toPath(),("file '"+f.getName()+"'\n").getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
            } catch (IOException e) {
                throw new RuntimeException("写入文件失败:"+f.getAbsoluteFile()+":"+e);
            }
        }
        // 使用命令合并视频
        // ffmpeg -f concat -i videoList.txt -c copy -o startName.+extendsName
        String cmd="ffmpeg -f concat -i "+VIDEO_LIST_FILE_NAME+" -c copy "+outFileName;
        System.out.println(cmd);
        try {
            ExecCmd(cmd);
        } catch (IOException e) {
            throw new RuntimeException("执行合并命令异常："+cmd+":"+e);
        }
        //拿到输出文件
        File newFile=path.resolve(outFileName).toFile();
        //输出文件进行存储
        if(newFile.exists()){
            String md5FileName= null;
            try {
                md5FileName = storageService.store(new FileInputStream(newFile),0L,extendsName,newFile.getName());
            } catch (FileNotFoundException e) {
                throw new RuntimeException("存储文件失败："+e);
            }
            //清理视频
            Arrays.stream(targerList).forEach(e -> e.delete());
            path.resolve(outFileName).toFile().delete();
            return md5FileName;
        }
        throw new RuntimeException("输出文件不存在:"+newFile.getAbsoluteFile());
    }

    public static int ExecCmd(String cmd) throws IOException {
        Runtime runTime = Runtime.getRuntime();
        Process process=runTime.exec(cmd,null,new File(GlobalConfig.RTMP_RECORD_PATH));
        try {
            process.waitFor();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return process.exitValue();
    }
}
